﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PushBox.Core
{
    /// <summary>
    /// 地图
    /// </summary>
    public class Map
    {
        /// <summary>
        /// 宽
        /// </summary>
        public int Width { get; set; }

        /// <summary>
        /// 高
        /// </summary>
        public int Height { get; set; }

        public Player Gamer { get; set; }

        public List<Box> Boxes { get; set; }

        public List<Target> Targets { get; set; }

        public List<Wall> Walls { get; set; }

        public delegate void ShowMap(Map map);  //委托 delegate  -> 请别的对象帮忙做某事 -> 代码里传递一个函数

        /// <summary>
        /// 在屏幕上绘制地图
        /// </summary>
        public ShowMap DoShowMap { get; set; }  //委托是一种类型，类型可以定义变量

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="mapInfo"></param>
        public Map(string mapInfo, ShowMap showMap)
        {
            this.DoShowMap = showMap;
            int x = 0, y = 0;
            Boxes = new List<Box>();
            Targets = new List<Target>();
            Walls = new List<Wall>();   //列表泛型，泛型：泛型<某一种类型>，泛型本身也是一种类型
            Gamer = new Player();
            foreach (char s in mapInfo)
            {
                if (s == '\n')
                {
                    this.Width = Math.Max(this.Width, x);
                    y++; x = 0;
                }
                else if (s == '@')
                {
                    Gamer.Map = this;
                    Gamer.X = x;
                    Gamer.Y = y;
                }
                else if (s == '#')
                {
                    Wall w = new Wall();
                    w.Map = this;
                    w.X = x;
                    w.Y = y;
                    this.Walls.Add(w);
                }
                else if (s == '+')
                {
                    Target t = new Target();
                    t.Map = this;
                    t.X = x;
                    t.Y = y;
                    this.Targets.Add(t);
                }
                else if (s == '*')
                {
                    Box b = new Box();
                    b.Map = this;
                    b.X = x;
                    b.Y = y;
                    this.Boxes.Add(b);
                }
                x++;
            }
            this.Height = y;
            this.DoShowMap(this);
        }

        public delegate void PassEventHandler(Map sender);

        public event PassEventHandler Passed;

        public void CheckPass()
        {
            if (this.Pass())
            {
                //向外通知，过关了
                this.Passed(this);
            }
        }

        /// <summary>
        /// 某个点上的物体
        /// </summary>
        public Position GetObject(int x, int y)
        {
            foreach (Box box in this.Boxes)
            {
                if (box.X == x && box.Y == y)
                {
                    return box;
                }
            }
            foreach (Wall wall in this.Walls)
            {
                if (wall.X == x && wall.Y == y)
                {
                    return wall;
                }
            }
            if (Gamer.X == x && Gamer.Y == y)
            {
                return Gamer;
            }
            foreach (Target target in this.Targets)
            {
                if (target.X == x && target.Y == y)
                {
                    return target;
                }
            }
            return null;
        }

        /// <summary>
        /// 是否通关
        /// </summary>
        /// <returns></returns>
        public bool Pass()
        {
            foreach (Target item in Targets)
            {
                Position p = GetObject(item.X, item.Y);
                if (p == null || !(p is Box))
                {
                    return false;
                }
            }
            return true;
        }
    }
}
